﻿using com.youzu.warh.protocol;
using LogSystem;
using NodeCanvas.BehaviourTrees;
using NodeCanvas.Framework;
using Pathfinding.RVO;
using RootMotion.Dynamics;
using System;
using UnityEngine;
using Yoozoo.Core.Common;
using Yoozoo.Mars.Got;

namespace Yoozoo.Gameplay.Liberty.AI
{
    public class AIEntity : MonoBehaviour
    {
        public int id;
        
        public AIData data;
        
        public AISeeker seeker;

        public RVOController rvoController;
        public CharacterController characterController;
        
        public BehaviourTreeOwner graph;
        public Blackboard blackboard;

        public BattleAgent battleAgent;
        public Collider onHitCollider;
        public Collider headCollider;

        public WeaponSystem WeaponSystem;
        // 当前武器 (近战、空闲状态 没有值)
        public LibertyWeapon weapon;
        // 当前弹夹
        public Transform magazine;

        private SkinnedMeshRenderer _skinnedMeshRenderer;

        public LibertyNpcLodController lodController;

        void Awake()
        {
            if (WeaponSystem == null)
            {
                WeaponSystem = new WeaponSystem();
            }
        }

        // 角色属性配置 readonly
        [SerializeField]
        private PbAIPropertyDataConfig _propertyDataConfig;
        public PbAIPropertyDataConfig propertyDataConfig => _propertyDataConfig;
        public void setPropertyDataConfig(PbAIPropertyDataConfig config)
        {
            if (config == null)
            {
                Debug.LogError(LogModule.LibertySceneBattle,$"角色属性不能设置为null");
                return;
            }
                
            _propertyDataConfig = config;
            data.hp = _propertyDataConfig.hp;
            data.reduceToughness = 0;
            data.maxToughness = _propertyDataConfig.toughness;
            WeaponSystem.ClearWeapons();
            WeaponSystem.InitWeapon(_propertyDataConfig, data.uniqueId==LibertyAIUtils.PLAYER_AI_ID);
            if (data.uniqueId == LibertyAIUtils.PLAYER_AI_ID)
            {
                // player
            }
            else
            {
                // npc
                WeaponSystem.SwitchEmpty();
                data.reduceToughness = _propertyDataConfig.toughness - 1;   // 保证npc第一次受击切换到受击
            }
        }

        // 表现层，如果后面需要逻辑和表现分离，从这里抽取出来
        public AIViewer viewer;
        public PuppetMaster puppetMaster;

        public NpcTrigger npcTrigger;
        // 生成数据，方便调试
        [SerializeField]
        private AIBirthData birthData;
        public AIBirthData BirthData
        {
            set => birthData = value;
            get => birthData;
        }

        void OnDisable()
        {
            // 卸掉武器
            // viewer?.animationAgent?.EnterBattleState(BattleState.None);  
            viewer?.animationAgent?.EnterAimingState(AimingState.None);
        }

        public void OnPlayerRadarUpdate()
        {
            if (seeker)
                seeker.OnPlayerRadarUpdate(this);
            
            //Debug.LogError(LogModule.LibertyScene,$"雷达刷新：{id}");
        }
        
        public void OnEnterPlayerRadar()
        {
            if (seeker)
                seeker.OnEnterPlayerRadar(this);
            //Debug.LogError(LogModule.LibertyScene,$"进入雷达：{id}");
        }
        
        public void OnExitPlayerRadar()
        {
            if (seeker)
                seeker.OnExitPlayerRadar(this);
            //Debug.LogError(LogModule.LibertyScene,$"退出雷达：{id}");
        }
        private float m_FixedTime;
        private int frameCount = 0;
        private void Update()
        {
            var interpAmount = (Time.time - m_FixedTime) / Time.fixedDeltaTime;
            if (float.IsNaN(interpAmount)) {
                interpAmount = 0;
            }

            UpdateViewer(interpAmount);

            if (_skinnedMeshRenderer == null)
            {
                if (viewer.animator!=null)
                {
                    _skinnedMeshRenderer = viewer.animator.GetComponentInChildren<SkinnedMeshRenderer>();
                }
            }

            if (_skinnedMeshRenderer!=null && graph !=null)
            {
                if (_skinnedMeshRenderer.isVisible)
                {
                    if (QualityManager.Inst.CurrentQuality >= QualityEnum.High)
                    {
                        graph.updateInterval = 0;
                    }
                    else
                    {
                        graph.updateInterval = 0.06f;
                    }
                }
                else
                {
                    graph.updateInterval = .3f;
                }
            }

            frameCount++;
        }

        private void UpdateViewer(float interpAmount)
        {
            if (!((data.npcStatus & NpcStatus.EnterCar) > 0 || (data.npcStatus & NpcStatus.ExitCar) > 0 || (data.npcStatus & NpcStatus.InCar) > 0))
            {
                if (viewer.viewerRoot!=null)
                {
                    viewer.viewerRoot.position = Vector3.Lerp(data.CurrentLerpPositin, data.TargetLerpPosition, interpAmount);
                    viewer.viewerRoot.rotation = Quaternion.Slerp(Quaternion.Euler(data.CurrentLerpRotation), Quaternion.Euler(data.TargetLerpRotation), interpAmount);
                    
                    //if (data.uniqueId != LibertyAIUtils.PLAYER_AI_ID)
                        //Debug.LogError(LogModule.LibertySceneBattle,$"frameCount {frameCount}     旋转5：{viewer.viewerRoot.eulerAngles}   CurrentLerpRotation:{data.CurrentLerpRotation}   TargetLerpRotation:{data.TargetLerpRotation}");
                }
            }
        }

        private void FixedUpdate()
        {
            if (!((data.npcStatus & NpcStatus.EnterCar) > 0 || (data.npcStatus & NpcStatus.ExitCar) > 0 || (data.npcStatus & NpcStatus.InCar) > 0))
            {
                RestoreFixedLocation();
            }
            m_FixedTime = Time.time;
        }
        
        /// <summary>
        /// 将上一帧的目标位置设置为当前位置
        /// </summary>
        public void RestoreFixedLocation()
        {
            data.SetCurrentPosition(data.TargetLerpPosition);
            data.CurrentLerpRotation = data.TargetLerpRotation;
            if (viewer.viewerRoot)
            {
                viewer.viewerRoot.position = data.TargetLerpPosition;
                viewer.viewerRoot.eulerAngles = data.CurrentLerpRotation;
                // if (data.uniqueId != LibertyAIUtils.PLAYER_AI_ID)
                //     Debug.LogError(LogModule.LibertySceneBattle,$"frameCount {frameCount}     旋转4：{viewer.viewerRoot.eulerAngles}  CurrentLerpRotation:{data.CurrentLerpRotation}   TargetLerpRotation:{data.TargetLerpRotation}");
            }
        }
        /// <summary>
        /// 设置需要插值的目标位置
        /// </summary>
        /// <param name="targetPosition"></param>
        public void AssignFixedLocation(Vector3 targetPosition)
        {
            viewer.viewerRoot.position = targetPosition;
            data.TargetLerpPosition = targetPosition;
        }
        
        /// <summary>
        /// 设置需要插值的目标位置
        /// </summary>
        /// <param name="targetPosition"></param>
        public void AssignFixedRotation(Vector3 targetRotation)
        {
            viewer.viewerRoot.eulerAngles = targetRotation;
            data.TargetLerpRotation = targetRotation;
            // if (data.uniqueId != LibertyAIUtils.PLAYER_AI_ID)
            //     Debug.LogError(LogModule.LibertySceneBattle,$"frameCount {frameCount}     旋转3：{targetRotation}  TargetLerpRotation:{data.TargetLerpRotation}");
        }
        /// <summary>
        /// 强行设置位置
        /// </summary>
        /// <param name="position"></param>
        public void SetPositionAndRotation(Vector3 position,Vector3 rotation)
        {
            data.SetCurrentPosition(position);
            data.TargetLerpPosition = position;
            viewer.viewerRoot.position = position;

            data.CurrentLerpRotation = rotation;
            data.TargetLerpRotation = rotation;
            viewer.viewerRoot.eulerAngles = rotation;
            // if (data.uniqueId != LibertyAIUtils.PLAYER_AI_ID)
            //     Debug.LogError(LogModule.LibertySceneBattle,$"frameCount {frameCount}     旋转1：{rotation}  TargetLerpRotation:{data.TargetLerpRotation}");
        }
        /// <summary>
        /// 强行设置位置
        /// </summary>
        /// <param name="position"></param>
        public void SetPositionAndRotation(Vector3 position)
        {
            data.SetCurrentPosition(position);
            data.TargetLerpPosition = position;
            viewer.viewerRoot.position = position;
        }
        public void SetRotation(Vector3 rotation)
        {
            data.CurrentLerpRotation = rotation;
            data.TargetLerpRotation = rotation;
            viewer.viewerRoot.eulerAngles = rotation;
            // if (data.uniqueId != LibertyAIUtils.PLAYER_AI_ID)
            // {
            //     Debug.LogError(LogModule.LibertySceneBattle,$"frameCount {frameCount}     旋转2：{rotation}    TargetLerpRotation:{data.TargetLerpRotation}");
            // }
        }
        
        public void ResetFixedPosition()
        {
            if (viewer != null && viewer.viewerRoot!=null)
            {
                if (data.TargetLerpRotation != Vector3.zero && 
                    data.TargetLerpPosition !=Vector3.zero && 
                    viewer.viewerRoot.position!=Vector3.zero&&
                    viewer.viewerRoot.eulerAngles!=Vector3.zero)
                {
                    data.TargetLerpPosition = viewer.viewerRoot.position;
                    data.TargetLerpRotation = viewer.viewerRoot.eulerAngles;
                }
                
            }
        }

        private void OnDestroy()
        {
            _skinnedMeshRenderer = null;
            if (battleAgent!=null)
            {
                battleAgent.OnReset();
            }
        }
    }

    [Serializable]
    public class AIViewer
    {
        public Transform transform;
        public Transform viewerRoot;
        public Animator animator;
        public BoneItemController boneItemController;
        public AnimationAgent animationAgent;
        public LocomotionAgent locomotionAgent;
    }
    
}
